<template>
  <el-dialog
    :model-value="visible"
    @update:model-value="$emit('update:visible', $event)"
    :title="`配置角色菜单 - ${role?.roleName || role?.name || ''}`"
    width="800px"
    :before-close="handleClose"
    destroy-on-close
  >
    <div v-loading="loading" class="menu-config-container">
      <!-- 菜单树形选择 -->
      <div class="menu-tree-section">
        <div class="section-title">
          <el-icon><Menu /></el-icon>
          选择可访问的菜单
        </div>
        <div class="tree-container">
          <el-tree
            ref="menuTreeRef"
            :data="menuList"
            :props="treeProps"
            show-checkbox
            node-key="id"
            :default-checked-keys="selectedMenuIds"
            :check-strictly="false"
            @check="handleMenuCheck"
            class="menu-tree"
          >
            <template #default="{ node, data }">
              <div class="tree-node">
                <div class="node-content">
                  <el-icon v-if="data.icon" class="node-icon">
                    <Menu />
                  </el-icon>
                  <span class="node-label">{{ data.menuName || data.name }}</span>
                </div>
                <div class="node-meta">
                  <el-tag v-if="data.path" size="small" type="info">{{ data.path }}</el-tag>
                </div>
              </div>
            </template>
          </el-tree>
        </div>
      </div>

      <!-- 已选菜单预览 -->
      <div class="selected-preview">
        <div class="section-title">
          <el-icon><View /></el-icon>
          已选菜单 ({{ selectedMenus.length }})
        </div>
        <div class="preview-list">
          <el-tag
            v-for="menu in selectedMenus"
            :key="menu.id"
            type="primary"
            class="menu-tag"
            closable
            @close="handleRemoveMenu(menu.id)"
          >
            <el-icon v-if="menu.icon"><Menu /></el-icon>
            {{ menu.menuName || menu.name }}
          </el-tag>
          <div v-if="selectedMenus.length === 0" class="empty-tip">
            暂未选择任何菜单
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleConfirm" :loading="saving">
          保存配置
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, computed, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { Menu, View, Setting, User, Document, Operation } from '@element-plus/icons-vue'
import { menuApi } from '@/api/menu'

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  role: {
    type: Object,
    default: null
  }
})

const emit = defineEmits(['update:visible', 'confirm'])

const loading = ref(false)
const saving = ref(false)
const menuTreeRef = ref(null)
const menuList = ref([])
const selectedMenuIds = ref([])

// 树形组件配置
const treeProps = {
  children: 'children',
  label: 'menuName'
}

// 计算已选菜单列表
const selectedMenus = computed(() => {
  const result = []
  const findMenus = (menus, ids) => {
    menus.forEach(menu => {
      if (ids.includes(menu.id)) {
        result.push(menu)
      }
      if (menu.children && menu.children.length > 0) {
        findMenus(menu.children, ids)
      }
    })
  }
  findMenus(menuList.value, selectedMenuIds.value)
  return result
})

// 监听对话框显示状态
watch(() => props.visible, (newVal) => {
  if (newVal && props.role) {
    loadMenus()
    loadRoleMenus()
  }
})

// 加载所有菜单
const loadMenus = async () => {
  try {
    loading.value = true
    const response = await menuApi.getMenus()
    
    if (response.data) {
      // 构建树形结构的菜单数据
      menuList.value = buildMenuTree(response.data)
    }
  } catch (error) {
    console.error('加载菜单失败:', error)
    ElMessage.error('加载菜单失败')
  } finally {
    loading.value = false
  }
}

// 加载角色已分配的菜单
const loadRoleMenus = async () => {
  if (!props.role?.id) return
  
  try {
    const response = await fetch(`/api/role/${props.role.id}/menus`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${localStorage.getItem('token')}`,
        'Content-Type': 'application/json'
      }
    })
    
    if (response.ok) {
      const result = await response.json()
      if (result.isSuccess && result.data) {
        selectedMenuIds.value = result.data.map(menu => menu.id)
        nextTick(() => {
          if (menuTreeRef.value) {
            menuTreeRef.value.setCheckedKeys(selectedMenuIds.value)
          }
        })
      }
    }
  } catch (error) {
    console.error('加载角色菜单失败:', error)
    ElMessage.error('加载角色菜单失败')
  }
}

// 构建菜单树形结构
const buildMenuTree = (menus) => {
  const menuMap = new Map()
  const roots = []
  
  // 先创建所有菜单节点
  menus.forEach(menu => {
    menuMap.set(menu.id, {
      ...menu,
      children: []
    })
  })
  
  // 构建父子关系
  menus.forEach(menu => {
    const menuNode = menuMap.get(menu.id)
    if (menu.parentId && menuMap.has(menu.parentId)) {
      menuMap.get(menu.parentId).children.push(menuNode)
    } else {
      roots.push(menuNode)
    }
  })
  
  return roots
}

// 处理菜单选择
const handleMenuCheck = (data, checked) => {
  // 获取当前选中的所有节点ID
  const checkedKeys = menuTreeRef.value.getCheckedKeys()
  const halfCheckedKeys = menuTreeRef.value.getHalfCheckedKeys()
  selectedMenuIds.value = [...checkedKeys, ...halfCheckedKeys]
}

// 移除选中的菜单
const handleRemoveMenu = (menuId) => {
  selectedMenuIds.value = selectedMenuIds.value.filter(id => id !== menuId)
  nextTick(() => {
    menuTreeRef.value.setCheckedKeys(selectedMenuIds.value)
  })
}

// 确认配置
const handleConfirm = async () => {
  if (!props.role?.id) {
    ElMessage.error('角色信息不完整')
    return
  }
  
  try {
    saving.value = true
    
    // 获取当前已分配的菜单
    const currentResponse = await fetch(`/api/role/${props.role.id}/menus`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${localStorage.getItem('token')}`,
        'Content-Type': 'application/json'
      }
    })
    
    let currentMenuIds = []
    if (currentResponse.ok) {
      const currentResult = await currentResponse.json()
      if (currentResult.isSuccess && currentResult.data) {
        currentMenuIds = currentResult.data.map(menu => menu.id)
      }
    }
    
    // 找出需要新增的菜单
    const menusToAdd = selectedMenuIds.value.filter(id => !currentMenuIds.includes(id))
    
    // 找出需要移除的菜单
    const menusToRemove = currentMenuIds.filter(id => !selectedMenuIds.value.includes(id))
    
    // 批量分配新菜单
    for (const menuId of menusToAdd) {
      await fetch(`/api/role/${props.role.id}/assign-menu/${menuId}`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token')}`,
          'Content-Type': 'application/json'
        }
      })
    }
    
    // 批量移除菜单
    for (const menuId of menusToRemove) {
      await fetch(`/api/role/${props.role.id}/remove-menu/${menuId}`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token')}`,
          'Content-Type': 'application/json'
        }
      })
    }
    
    ElMessage.success('菜单配置保存成功')
    emit('confirm')
    handleClose()
  } catch (error) {
    console.error('保存菜单配置失败:', error)
    ElMessage.error('保存菜单配置失败')
  } finally {
    saving.value = false
  }
}

// 关闭对话框
const handleClose = () => {
  emit('update:visible', false)
  // 重置数据
  selectedMenuIds.value = []
  menuList.value = []
}
</script>

<style scoped>
.menu-config-container {
  min-height: 400px;
}

.section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 16px;
  font-size: 14px;
}

.menu-tree-section {
  margin-bottom: 24px;
}

.tree-container {
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  max-height: 300px;
  overflow-y: auto;
  padding: 12px;
}

.menu-tree {
  width: 100%;
}

.tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}

.node-content {
  display: flex;
  align-items: center;
  gap: 6px;
}

.node-icon {
  color: #606266;
  font-size: 16px;
}

.node-label {
  color: #2c3e50;
}

.node-meta {
  display: flex;
  align-items: center;
  gap: 8px;
}

.selected-preview {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 16px;
}

.preview-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 32px;
  align-items: flex-start;
}

.menu-tag {
  display: flex;
  align-items: center;
  gap: 4px;
}

.empty-tip {
  color: #909399;
  font-size: 14px;
  font-style: italic;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

:deep(.el-tree-node__content) {
  height: 36px;
  border-radius: 4px;
}

:deep(.el-tree-node__content:hover) {
  background-color: #f5f7fa;
}

:deep(.el-tree-node__expand-icon) {
  color: #c0c4cc;
}

:deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
  background-color: #409eff;
  border-color: #409eff;
}
</style>
